package com.xbongbong.paas.service.workflow.setting.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.config.constant.WorkflowOperateLogicConstant;
import com.xbongbong.paas.config.enums.WorkflowConditionEnum;
import com.xbongbong.paas.config.enums.WorkflowSortFieldEnum;
import com.xbongbong.paas.constant.AdvancedRuleFieldOperatorConstant;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.constant.RuleFieldOperatorConstant;
import com.xbongbong.paas.constant.RuleFieldRelationConstant;
import com.xbongbong.paas.domain.entity.PaasFormEntity;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.clazz.ConditionClass;
import com.xbongbong.paas.enums.formula.enums.RuleFormulaExplainEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.field.LinkInfoPojo;
import com.xbongbong.paas.field.SubFormPoJo;
import com.xbongbong.paas.help.ConditionListHelp;
import com.xbongbong.paas.help.FormExplainHelp;
import com.xbongbong.sys.help.PackageHelp;
import com.xbongbong.paas.help.ProFormHelp;
import com.xbongbong.paas.help.WorkflowNodeHelp;
import com.xbongbong.paas.pojo.workflow.explains.WorkflowConditionFieldPojo;
import com.xbongbong.paas.pojo.workflow.explains.WorkflowConditionListPojo;
import com.xbongbong.paas.pojo.workflow.explains.WorkflowSourceFieldPojo;
import com.xbongbong.paas.pojo.workflow.explains.dto.WorkflowConditionDTO;
import com.xbongbong.paas.pojo.workflow.explains.dto.WorkflowDynamicManagerDTO;
import com.xbongbong.paas.pojo.workflow.explains.dto.WorkflowFilterConditionFieldDTO;
import com.xbongbong.paas.pojo.workflow.explains.dto.WorkflowInsertNodeOperatorFieldDTO;
import com.xbongbong.paas.pojo.workflow.explains.dto.WorkflowOperatorFieldDTO;
import com.xbongbong.paas.pojo.workflow.explains.dto.WorkflowSortFieldDTO;
import com.xbongbong.paas.pojo.workflow.explains.dto.WorkflowTitleFieldDTO;
import com.xbongbong.paas.pojo.workflow.explains.vo.WorkflowConditionVO;
import com.xbongbong.paas.pojo.workflow.explains.vo.WorkflowDynamicManagerVO;
import com.xbongbong.paas.pojo.workflow.explains.vo.WorkflowFilterConditionFieldVO;
import com.xbongbong.paas.pojo.workflow.explains.vo.WorkflowOperatorFieldVO;
import com.xbongbong.paas.pojo.workflow.explains.vo.WorkflowSortFieldVO;
import com.xbongbong.paas.pojo.workflow.explains.vo.WorkflowSourceOperatorFieldVO;
import com.xbongbong.paas.pojo.workflow.explains.vo.WorkflowTitleFieldVO;
import com.xbongbong.paas.service.workflow.setting.WorkflowExplainService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.helper.ReflectHelper;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.util.WorkflowNodeUtil;
import com.xbongbong.pro.constant.I18nStringConstant;
import com.xbongbong.pro.enums.PackageTypeEnum;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.businessrule.enums.RuleOperatorBusinessFieldEnum;
import com.xbongbong.pro.enums.businessrule.enums.RuleOperatorFieldEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.workflow.WorkflowSystemFieldEnum;
import com.xbongbong.pro.enums.workflow.WorkflowValueTypeEnum;
import com.xbongbong.pro.formexplain.pojo.FieldAndLogicPojo;
import com.xbongbong.pro.formexplain.pojo.LogicPojo;
import com.xbongbong.pro.formexplain.pojo.ValueTypePojo;
import com.xbongbong.pro.formexplain.pojo.dto.FilterExplainByRuleDTO;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.WorkOrderExplainEntity;
import com.xbongbong.saas.domain.entity.WorkOrderFormEntity;
import com.xbongbong.saas.enums.ShowTypeEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.ContactEnum;
import com.xbongbong.saas.enums.business.PaymentSheetEnum;
import com.xbongbong.util.FilterExplainUtil;
import com.xbongbong.workflow.domain.entity.WorkflowEntity;
import com.xbongbong.workflow.domain.entity.WorkflowNodeEntity;
import com.xbongbong.workflow.enums.WorkflowNodeTypeEnum;
import com.xbongbong.workflow.model.WorkflowModel;
import com.xbongbong.workflow.model.WorkflowNodeModel;
import org.apache.commons.collections4.CollectionUtils;
import org.elasticsearch.search.sort.SortOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author 吴峰
 * @date 2021/05/25 14:59
 */
@Service("workflowExplainService")
public class WorkflowExplainServiceImpl implements WorkflowExplainService {

    private static final Logger LOGGER = LoggerFactory.getLogger(WorkflowExplainServiceImpl.class);


    public static final String SYSTEM_FIELD = "constant.WorkflowExplainServiceImpl.system_field";

    public static final String COMMIT_USER = "constant.WorkflowExplainServiceImpl.commit_user";

    public static final String TRIGGER_FORM = "constant.WorkflowExplainServiceImpl.trigger_form";

    @Resource
    private ProFormHelp proFormHelp;
    @Resource
    private WorkflowNodeModel workflowNodeModel;
    @Resource
    private PackageHelp packageHelp;
    @Resource
    private WorkflowNodeHelp workflowNodeHelp;
    @Resource
    private FormExplainHelp formExplainHelp;
    @Resource
    private WorkflowModel workflowModel;

    @Override
    public WorkflowConditionVO conditionNodeFieldList(WorkflowConditionDTO workflowConditionDTO) throws XbbException {
        WorkflowConditionVO workflowConditionVO = new WorkflowConditionVO();
        try {
            String corpid = workflowConditionDTO.getCorpid();
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("workflowId", workflowConditionDTO.getWorkflowId());
            param.put(StringConstant.CORPID, corpid);
            param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
            param.put("type", WorkflowNodeTypeEnum.START_NODE.getType());
            List<WorkflowNodeEntity> workflowNodeList = workflowNodeModel.findEntitys(param);
            Set<Long> formIdList = new HashSet<>();
            Set<Long> workOrderFormIdList = new HashSet<>();
            workflowNodeList.forEach(item->{
                if (Objects.equals(XbbRefTypeEnum.WORK_ORDER.getCode(), item.getBusinessType())) {
                    workOrderFormIdList.add(item.getFormId());
                } else {
                    formIdList.add(item.getFormId());
                }
            });

            Map<Long, PaasFormExplainEntity> formExplainMap = proFormHelp.getFormExplainMap(formIdList, corpid);
            Map<Long, List<WorkflowConditionFieldPojo>> formFieldAndLogicList = new HashMap<>(formExplainMap.size());
            for (Map.Entry<Long, PaasFormExplainEntity> entry : formExplainMap.entrySet()) {
                Long key = entry.getKey();
                PaasFormExplainEntity explainEntity = entry.getValue();
                List<WorkflowConditionFieldPojo> fieldAndLogicPojos = getExplainMapByConditionNode(explainEntity.getExplains());
                formFieldAndLogicList.put(key, fieldAndLogicPojos);
            }
            Map<Long, WorkOrderExplainEntity> workOrderFormExplainMap = proFormHelp.getWorkOrderFormExplainMap(workOrderFormIdList, corpid);
            Map<Long, List<WorkflowConditionFieldPojo>> workOrderFormFieldAndLogicList = new HashMap<>(formExplainMap.size());
            for (Map.Entry<Long, WorkOrderExplainEntity> entry : workOrderFormExplainMap.entrySet()) {
                Long key = entry.getKey();
                WorkOrderExplainEntity explainEntity = entry.getValue();
                List<WorkflowConditionFieldPojo> fieldAndLogicPojos = getExplainMapByConditionNode(explainEntity.getExplains());
                workOrderFormFieldAndLogicList.put(key, fieldAndLogicPojos);
            }
            List<WorkflowConditionListPojo> conditionList = new ArrayList<>();
            workflowNodeList.forEach(item->{
                WorkflowConditionListPojo workflowConditionListPojo = new WorkflowConditionListPojo();
                workflowConditionListPojo.setName(item.getName());
                workflowConditionListPojo.setWorkflowNodeId(item.getId());
                workflowConditionListPojo.setSaasMark(item.getSaasMark());
                workflowConditionListPojo.setBusinessType(item.getBusinessType());
                workflowConditionListPojo.setFormId(item.getFormId());
                if (Objects.equals(item.getBusinessType(), XbbRefTypeEnum.WORK_ORDER.getCode())) {

                    workflowConditionListPojo.setExplainList(workOrderFormFieldAndLogicList.get(item.getFormId()));
                } else {
                    workflowConditionListPojo.setExplainList(formFieldAndLogicList.get(item.getFormId()));
                }
                conditionList.add(workflowConditionListPojo);
            });
            workflowConditionVO.setConditionList(conditionList);

        } catch (XbbException e ) {
            throw e;
        } catch (Exception e) {
            LOGGER.error("WorkflowSetServiceImpl.get error：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        return workflowConditionVO;
    }


    @Override
    public WorkflowSortFieldVO sortFieldList(WorkflowSortFieldDTO workflowSortFieldDTO) throws XbbException {
        WorkflowSortFieldVO workflowSortFieldVO = new WorkflowSortFieldVO();
        try {
            String corpid = workflowSortFieldDTO.getCorpid();
            PaasFormExplainEntity paasFormExplainEntity = proFormHelp.getExplainEntity(corpid, workflowSortFieldDTO.getFormId(), workflowSortFieldDTO.getBusinessType());
            List<FieldAttrEntity> explainList = JSON.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);

            Iterator<FieldAttrEntity> iterator = explainList.iterator();
            while (iterator.hasNext()) {
                FieldAttrEntity fieldAttrEntity = iterator.next();
                if (Objects.equals(0, fieldAttrEntity.getVisible()) || !Objects.equals(1, fieldAttrEntity.getIsOpen())) {
                    // 去掉不可以排序的字段
                    iterator.remove();
                    continue;
                }
                Integer showType = fieldAttrEntity.getShowType();
                Boolean invisible = Objects.nonNull(fieldAttrEntity.getShowType()) && (ShowTypeEnum.LIST.getCode() == showType || ShowTypeEnum.DETAIL.getCode() == showType
                        || ShowTypeEnum.LIST_DETAIL.getCode() == showType || ShowTypeEnum.NONE.getCode() == showType);
                if (invisible || Objects.equals(1, fieldAttrEntity.getDisableListSort())) {
                    // 去掉不可以排序的字段
                    iterator.remove();
                    continue;
                }
                if (!WorkflowSortFieldEnum.canSort(fieldAttrEntity.getFieldType())) {
                    // 去掉不可以排序的字段
                    iterator.remove();
                }
            }
            workflowSortFieldVO.setExplainList(explainList);
        } catch (XbbException e ) {
            throw e;
        } catch (Exception e) {
            LOGGER.error("WorkflowSetServiceImpl.sortFieldList error：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        return workflowSortFieldVO;
    }

    @Override
    public WorkflowSourceOperatorFieldVO sourceOperatorField(WorkflowInsertNodeOperatorFieldDTO workflowInsertNodeOperatorFieldDTO) throws XbbException {
        WorkflowSourceOperatorFieldVO workflowUpdateFieldVO = new WorkflowSourceOperatorFieldVO();
        try {
            Long workflowId = workflowInsertNodeOperatorFieldDTO.getWorkflowId();
            String corpid = workflowInsertNodeOperatorFieldDTO.getCorpid();

            List<WorkflowNodeEntity> upNodeList = new ArrayList<>();
            if (Objects.equals(WorkflowNodeTypeEnum.CREATE_NODE.getType(), workflowInsertNodeOperatorFieldDTO.getType())
                && Objects.equals(BasicConstant.TWO, workflowInsertNodeOperatorFieldDTO.getChooseDataSource())) {
                upNodeList = workflowNodeModel.getByIdIn(workflowInsertNodeOperatorFieldDTO.getTargetNodeId(), corpid);
                List<Integer> nodeList = Arrays.asList(WorkflowNodeTypeEnum.SINGLE_DATA_NODE.getType());
                List<WorkflowNodeEntity> list = workflowNodeModel.getWorkflowNodeList( corpid, workflowId, null);
                List<WorkflowNodeEntity> singleDataNodeList = WorkflowNodeUtil.getUpNodeList(list, workflowInsertNodeOperatorFieldDTO.getNodeId(), nodeList);
                upNodeList.addAll(singleDataNodeList);
            } else if (Objects.equals(WorkflowNodeTypeEnum.CREATE_NODE.getType(), workflowInsertNodeOperatorFieldDTO.getType())
                    && Objects.equals(BasicConstant.ONE, workflowInsertNodeOperatorFieldDTO.getChooseDataSource())) {
                List<WorkflowNodeEntity> list = workflowNodeModel.getWorkflowNodeList( corpid, workflowId, null);
                List<Integer> nodeList = Arrays.asList(WorkflowNodeTypeEnum.START_NODE.getType(), WorkflowNodeTypeEnum.SINGLE_DATA_NODE.getType());
                upNodeList = WorkflowNodeUtil.getUpNodeList(list, workflowInsertNodeOperatorFieldDTO.getNodeId(), nodeList);
            } else {
                upNodeList = workflowNodeModel.getByIdIn(workflowInsertNodeOperatorFieldDTO.getTargetNodeId(), corpid);
            }
            Set<Long> formIdList = new HashSet<>();
            Set<Long> workOrderIdList = new HashSet<>();
            Long updateNodeId = workflowInsertNodeOperatorFieldDTO.getUpdateNodeId();
            // 获取数据来源节点
            WorkflowNodeEntity dataNode = null;
            if (Objects.nonNull(updateNodeId)) {
                for (WorkflowNodeEntity item : upNodeList) {
                    if (Objects.equals(updateNodeId, item.getId())) {
                        dataNode = item;
                    }
                }
            }
            WorkflowNodeUtil.getFormIdByNode(upNodeList, workOrderIdList, formIdList);
            Object clazz = new RuleFieldOperatorConstant();
            if (Objects.equals(WorkflowValueTypeEnum.FORMULA.getType(), workflowInsertNodeOperatorFieldDTO.getValueType())) {
                clazz = new AdvancedRuleFieldOperatorConstant();
            }
            Map<Long, PaasFormEntity> formMap = proFormHelp.getFormMap(formIdList, corpid, DelEnum.NORMAL.getDel());
            Map<Long, PaasFormExplainEntity> formExplainMap = proFormHelp.getFormExplainMap(formIdList, corpid);
            Map<Long, List<FieldAttrEntity>> explainFieldMap = new HashMap<>(formExplainMap.size());
            for (Map.Entry<Long, PaasFormExplainEntity> entry : formExplainMap.entrySet()) {
                Long key = entry.getKey();
                PaasFormExplainEntity explainEntity = entry.getValue();
                List<FieldAttrEntity> explainList = getFieldList(dataNode, workflowInsertNodeOperatorFieldDTO, clazz, explainEntity.getFormId(), explainEntity.getBusinessType(), explainEntity.getSaasMark(), explainEntity.getExplains(), false);
                formExplainHelp.addDataIdInBusinessRule(explainList, workflowInsertNodeOperatorFieldDTO.getFieldType(), explainEntity.getFormId(), explainEntity.getBusinessType(),
                        workflowInsertNodeOperatorFieldDTO.getLinkInfo());
                explainFieldMap.put(key, explainList);
            }
            Map<Long, WorkOrderFormEntity> workOrderFormMap = proFormHelp.getWorkOrderFormMap(workOrderIdList, corpid, DelEnum.NORMAL.getDel());
            Map<Long, WorkOrderExplainEntity> workOrderFormExplainMap = proFormHelp.getWorkOrderFormExplainMap(workOrderIdList, corpid);
            Map<Long, List<FieldAttrEntity>> workOrderFormFieldMap = new HashMap<>(formExplainMap.size());
            for (Map.Entry<Long, WorkOrderExplainEntity> entry : workOrderFormExplainMap.entrySet()) {
                Long key = entry.getKey();
                WorkOrderExplainEntity explainEntity = entry.getValue();
                List<FieldAttrEntity> explainList = getFieldList(dataNode, workflowInsertNodeOperatorFieldDTO, clazz, explainEntity.getFormId(), XbbRefTypeEnum.WORK_ORDER.getCode(),
                        SaasMarkEnum.SAAS.getCode(), explainEntity.getExplains(), false);
                formExplainHelp.addDataIdInBusinessRule(explainList, workflowInsertNodeOperatorFieldDTO.getFieldType(), explainEntity.getFormId(), XbbRefTypeEnum.WORK_ORDER.getCode(),
                        workflowInsertNodeOperatorFieldDTO.getLinkInfo());
                workOrderFormFieldMap.put(key, explainList);
            }
            if (Objects.equals(WorkflowNodeTypeEnum.UPDATE_NODE.getType(), workflowInsertNodeOperatorFieldDTO.getType())) {

                Map<Long, String> subFormMap = workflowNodeHelp.getSubForm(workflowInsertNodeOperatorFieldDTO.getUpdateNodeId(), corpid, workflowInsertNodeOperatorFieldDTO.getValueType());
                List<WorkflowSourceFieldPojo> nodeFieldList = getFieldList(upNodeList, workOrderFormFieldMap, explainFieldMap, true, subFormMap, formMap, workOrderFormMap);
                workflowUpdateFieldVO.setNodeFieldList(nodeFieldList);
            } else {
                List<WorkflowSourceFieldPojo> nodeFieldList = getFieldList(upNodeList, workOrderFormFieldMap, explainFieldMap, false, null, formMap, workOrderFormMap);
                workflowUpdateFieldVO.setNodeFieldList(nodeFieldList);

            }
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOGGER.error("WorkflowSetServiceImpl.insertNodeOperatorField error：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        return workflowUpdateFieldVO;
    }



    @Override
    public WorkflowOperatorFieldVO getOperatorField(WorkflowOperatorFieldDTO workflowOperatorFieldDTO) throws XbbException {
        WorkflowOperatorFieldVO workflowOperatorFieldVO = new WorkflowOperatorFieldVO();
        try {
            String corpid = workflowOperatorFieldDTO.getCorpid();
            Integer feeType = packageHelp.getFeeType(workflowOperatorFieldDTO.getCorpid());
            boolean standard = Objects.equals(PackageTypeEnum.ADVANCED.getType(), feeType) || Objects.equals(PackageTypeEnum.ULTIMATE.getType(), feeType);

            PaasFormExplainEntity paasFormExplainEntity = proFormHelp.getExplainEntity(corpid, workflowOperatorFieldDTO.getFormId(), workflowOperatorFieldDTO.getBusinessType());

            Map<Integer, List<String>> fieldBlockMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            fieldBlockMap.put(XbbRefTypeEnum.PAYMENT_SHEET.getCode(), Arrays.asList(PaymentSheetEnum.PAY_METHOD.getAttr(), PaymentSheetEnum.FUND_ACCOUNT.getAttr()));
            String subForm = "";
            if (Objects.equals(WorkflowNodeTypeEnum.UPDATE_NODE.getType(), workflowOperatorFieldDTO.getType())) {
                // 获取条件中含有的子表单字段
                subForm = workflowNodeHelp.getSubFormAttr(workflowOperatorFieldDTO.getUpdateNodeId(), corpid);
            }
            if(paasFormExplainEntity != null ) {
                Integer businessType = paasFormExplainEntity.getBusinessType();
                if (Objects.isNull(businessType)) {
                    // 工单的特殊处理
                    businessType = workflowOperatorFieldDTO.getBusinessType();
                }
                List<FieldAndLogicPojo> explainList = new ArrayList<>();

                List<FieldAttrEntity> fieldList = JSON.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
                Iterator<FieldAttrEntity> iterator = fieldList.iterator();
                List<FieldAndLogicPojo> conditionFieldList = new ArrayList<>();
                List<FieldAndLogicPojo> operatorFieldList = new ArrayList<>();
                conditionFieldList.addAll(explainList);
                while (iterator.hasNext()) {
                    // 过滤掉非自定义字段和子表单
                    FieldAttrEntity fieldAttrEntity = iterator.next();
                    Integer fieldType = fieldAttrEntity.getFieldType();
                    if (fieldBlockMap.containsKey(businessType)) {
                        List<String> fieldBlockList = fieldBlockMap.get(businessType);
                        if (fieldBlockList.contains(fieldAttrEntity.getAttr())) {
                            continue;
                        }
                    }
                    if (Objects.equals(FieldTypeEnum.SUB_FORM.getType(), fieldType)) {
                        List<? extends FieldAttrEntity> subFieldList = fieldAttrEntity.getSubForm().getItems();
                        for (FieldAttrEntity subField : subFieldList) {
                            if (Objects.equals(WorkflowNodeTypeEnum.UPDATE_NODE.getType(), workflowOperatorFieldDTO.getType()) && !Objects.equals(subField.getParentAttr(), subForm)) {
                                // 更新节点的子表单字段，需要根据条件来获取是否有子表单字段，如果没有，则无需返回
                                // 新建节点的子表单字段，由前端开发人员在页面上进行控制
                                continue;
                            }
                            FieldAndLogicPojo operatorField = getOperatorObject(subField, businessType, WorkflowOperateLogicConstant.class, standard);
                            if (Objects.nonNull(operatorField)) {
                                operatorField.setAttr(fieldAttrEntity.getAttr()+ "."+ subField.getAttr());
                                operatorField.setAttrName(fieldAttrEntity.getAttrName()+ "."+ subField.getAttrName());
                                operatorFieldList.add(operatorField);
                            }

                        }
                    } else {
                        // 操作方式
                        FieldAndLogicPojo operatorField = getOperatorObject(fieldAttrEntity, businessType, WorkflowOperateLogicConstant.class, standard);
                        if (Objects.nonNull(operatorField)) {
                            operatorFieldList.add(operatorField);
                        }
                    }
                }
                workflowOperatorFieldVO.setFormExplainList(conditionFieldList);
                workflowOperatorFieldVO.setOperatorFieldList(operatorFieldList);
                workflowOperatorFieldVO.setAppId(paasFormExplainEntity.getAppId());
                workflowOperatorFieldVO.setFormExplainId(paasFormExplainEntity.getFormId());
                workflowOperatorFieldVO.setFormId(paasFormExplainEntity.getFormId());
                workflowOperatorFieldVO.setFieldList(fieldList);
            } else {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
            }
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOGGER.error("WorkflowSetServiceImpl.getFieldInUpdateNode error：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        return workflowOperatorFieldVO;
    }


    @Override
    public WorkflowTitleFieldVO getTitleField(WorkflowTitleFieldDTO workflowTitleFieldDTO) throws XbbException {
        WorkflowTitleFieldVO workflowTitleFieldVO = new WorkflowTitleFieldVO();
        try {
            Long workflowId = workflowTitleFieldDTO.getWorkflowId();
            String corpid = workflowTitleFieldDTO.getCorpid();
            String prevId = workflowTitleFieldDTO.getPrevId();
            Integer type = workflowTitleFieldDTO.getNodeType();
            List<WorkflowNodeEntity> workflowNodeList = workflowNodeModel.getWorkflowNodeList(corpid, workflowId, " priority " + SortOrder.ASC);
            // 获取标题可以选择到的节点
            List<Integer> nodeList = getNodeList(type);

            List<WorkflowNodeEntity> upNodeList = WorkflowNodeUtil.getUpNodeList(workflowNodeList, prevId, nodeList);
            Set<Long> formIdList = new HashSet<>();
            Set<Long> workOrderIdList = new HashSet<>();
            upNodeList.forEach(item -> {
                if (Objects.equals(XbbRefTypeEnum.WORK_ORDER.getCode(), item.getBusinessType())) {
                    workOrderIdList.add(item.getFormId());
                } else {
                    formIdList.add(item.getFormId());
                }
            });
            Map<Long, PaasFormExplainEntity> formExplainMap = proFormHelp.getFormExplainMap(formIdList, corpid);
            Map<Long, List<FieldAttrEntity>> explainFieldMap = new HashMap<>(formExplainMap.size());
            for (Map.Entry<Long, PaasFormExplainEntity> entry : formExplainMap.entrySet()) {
                Long key = entry.getKey();
                PaasFormExplainEntity explainEntity = entry.getValue();
                List<FieldAttrEntity> explainList = getExplainByTitle(explainEntity.getExplains());
                explainFieldMap.put(key, explainList);
            }
            Map<Long, WorkOrderExplainEntity> workOrderFormExplainMap = proFormHelp.getWorkOrderFormExplainMap(workOrderIdList, corpid);
            Map<Long, List<FieldAttrEntity>> workOrderFormFieldMap = new HashMap<>(formExplainMap.size());
            for (Map.Entry<Long, WorkOrderExplainEntity> entry : workOrderFormExplainMap.entrySet()) {
                Long key = entry.getKey();
                WorkOrderExplainEntity explainEntity = entry.getValue();
                List<FieldAttrEntity> explainList = getExplainByTitle(explainEntity.getExplains());
                workOrderFormFieldMap.put(key, explainList);
            }
            Map<Long, PaasFormEntity> formMap = proFormHelp.getFormMap(formIdList, corpid, DelEnum.NORMAL.getDel());
            Map<Long, WorkOrderFormEntity> workOrderFormMap = proFormHelp.getWorkOrderFormMap(workOrderIdList, corpid, DelEnum.NORMAL.getDel());
            List<WorkflowSourceFieldPojo> nodeFieldList = getFieldList(upNodeList, workOrderFormFieldMap, explainFieldMap, false, null, formMap, workOrderFormMap);
            nodeFieldList.forEach(item->{
                item.setOpen(BasicConstant.ONE);
            });
            if (!Objects.equals(WorkflowNodeTypeEnum.SEND_MESSAGE_NODE.getType(), type)){
                // 除了消息节点，其他的需要返回系统字段；
                List<FieldAttrEntity> explainList = new ArrayList<>();

                FieldAttrEntity commitUser = new FieldAttrEntity();
                commitUser.setAttrName(I18nMessageUtil.getMessage(COMMIT_USER));
                commitUser.setAttr(WorkflowSystemFieldEnum.COMMIT_USER.getProperty());

                FieldAttrEntity triggerForm = new FieldAttrEntity();
                triggerForm.setAttrName(I18nMessageUtil.getMessage(TRIGGER_FORM));
                triggerForm.setAttr(WorkflowSystemFieldEnum.TRIGGER_FORM.getProperty());
                explainList.add(commitUser);
                explainList.add(triggerForm);
                WorkflowSourceFieldPojo workflowSourceFieldPojo = new WorkflowSourceFieldPojo(I18nMessageUtil.getMessage(SYSTEM_FIELD), 0L, 0L, 0,
                    0, 1, 0, explainList);
                workflowSourceFieldPojo.setOpen(BasicConstant.ONE);
                nodeFieldList.add(workflowSourceFieldPojo);
            }
            workflowTitleFieldVO.setNodeFieldList(nodeFieldList);
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOGGER.error("WorkflowSetServiceImpl.getTitleField error：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        return workflowTitleFieldVO;
    }


    @Override
    public WorkflowFilterConditionFieldVO getFilterConditionField(WorkflowFilterConditionFieldDTO workflowFilterConditionFieldDTO) throws XbbException {
        WorkflowFilterConditionFieldVO workflowUpdateFieldVO = new WorkflowFilterConditionFieldVO();
        try {
            Long workflowId = workflowFilterConditionFieldDTO.getWorkflowId();
            String corpid = workflowFilterConditionFieldDTO.getCorpid();
            String prevId = workflowFilterConditionFieldDTO.getPrevId();
            WorkflowEntity workflowEntity = workflowModel.getByKey(workflowId, corpid);

            List<WorkflowNodeEntity> workflowNodeList = workflowNodeModel.getWorkflowNodeList(corpid, workflowId, " priority " + SortOrder.ASC);
            List<Integer> nodeList = Arrays.asList(WorkflowNodeTypeEnum.START_NODE.getType());
            List<WorkflowNodeEntity> upNodeList = WorkflowNodeUtil.getUpNodeList(workflowNodeList, prevId, nodeList);
            Set<Long> formIdList = new HashSet<>();
            Set<Long> workOrderIdList = new HashSet<>();
            upNodeList.forEach(item->{
                if(Objects.equals(XbbRefTypeEnum.WORK_ORDER.getCode(), item.getBusinessType())) {
                    workOrderIdList.add(item.getFormId());
                } else {
                    formIdList.add(item.getFormId());
                }
            });
            WorkflowInsertNodeOperatorFieldDTO workflowInsertNodeOperatorFieldDTO = new WorkflowInsertNodeOperatorFieldDTO(workflowFilterConditionFieldDTO.getWorkflowId(), workflowFilterConditionFieldDTO.getWorkflowNodeId(), workflowFilterConditionFieldDTO.getFormId(),
                    workflowFilterConditionFieldDTO.getSaasMark(), workflowFilterConditionFieldDTO.getBusinessType(), workflowFilterConditionFieldDTO.getNodeId(), workflowFilterConditionFieldDTO.getPrevId(),
                    workflowFilterConditionFieldDTO.getFieldType(), workflowFilterConditionFieldDTO.getLinkAttr(), workflowFilterConditionFieldDTO.getValueType(), workflowFilterConditionFieldDTO.getLinkInfo(),
                    workflowFilterConditionFieldDTO.getLinkedType());
            Map<Long, PaasFormExplainEntity> formExplainMap = proFormHelp.getFormExplainMap(formIdList, corpid);
            Map<Long, List<FieldAttrEntity>> explainFieldMap = new HashMap<>(formExplainMap.size());
            FilterExplainByRuleDTO filterExplainByRuleDTO = new FilterExplainByRuleDTO(workflowEntity.getFormId(), workflowEntity.getBusinessType(), workflowFilterConditionFieldDTO.getSaasMark(), workflowFilterConditionFieldDTO.getLinkInfo(), workflowFilterConditionFieldDTO.getLinkedType(), corpid);
            for (Map.Entry<Long, PaasFormExplainEntity> entry : formExplainMap.entrySet()) {
                Long key = entry.getKey();
                PaasFormExplainEntity explainEntity = entry.getValue();
                List<FieldAttrEntity> explainList = getExplainByUpdateNode(workflowInsertNodeOperatorFieldDTO, new RuleFieldRelationConstant(), explainEntity.getFormId(),
                        explainEntity.getBusinessType(), explainEntity.getSaasMark(), explainEntity.getExplains(), true);
                filterExplainByRuleDTO.setFormId(key);
                formExplainHelp.addDataIdAsCondition(explainList, workflowFilterConditionFieldDTO.getFieldType(), filterExplainByRuleDTO, false);
                explainFieldMap.put(key, explainList);
            }
            Map<Long, WorkOrderExplainEntity> workOrderFormExplainMap = proFormHelp.getWorkOrderFormExplainMap(workOrderIdList, corpid);
            Map<Long, List<FieldAttrEntity>> workOrderFormFieldMap = new HashMap<>(formExplainMap.size());
            for (Map.Entry<Long, WorkOrderExplainEntity> entry : workOrderFormExplainMap.entrySet()) {
                Long key = entry.getKey();
                WorkOrderExplainEntity explainEntity = entry.getValue();
                List<FieldAttrEntity> explainList = getExplainByUpdateNode(workflowInsertNodeOperatorFieldDTO, new RuleFieldRelationConstant(),
                        explainEntity.getFormId(), XbbRefTypeEnum.WORK_ORDER.getCode(),
                        SaasMarkEnum.SAAS.getCode(), explainEntity.getExplains(), true);
                filterExplainByRuleDTO.setFormId(key);
                formExplainHelp.addDataIdAsCondition(explainList, workflowFilterConditionFieldDTO.getFieldType(), filterExplainByRuleDTO, false);
                workOrderFormFieldMap.put(key, explainList);
            }
            Map<Long, WorkOrderFormEntity> workOrderFormMap = proFormHelp.getWorkOrderFormMap(workOrderIdList, corpid, DelEnum.NORMAL.getDel());
            Map<Long, PaasFormEntity> formMap = proFormHelp.getFormMap(formIdList, corpid, DelEnum.NORMAL.getDel());
            List<WorkflowSourceFieldPojo> nodeFieldList = getFieldList(upNodeList, workOrderFormFieldMap, explainFieldMap, false, null, formMap, workOrderFormMap);
            workflowUpdateFieldVO.setNodeFieldList(nodeFieldList);
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOGGER.error("WorkflowSetServiceImpl.updateFieldList error：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        return workflowUpdateFieldVO;
    }


    @Override
    public WorkflowDynamicManagerVO dynamicManager(WorkflowDynamicManagerDTO workflowDynamicManagerDTO) throws XbbException {
        try {
            Long workflowId = workflowDynamicManagerDTO.getWorkflowId();
            String corpid = workflowDynamicManagerDTO.getCorpid();
            String prevId = workflowDynamicManagerDTO.getPrevId();
            List<WorkflowNodeEntity> workflowNodeList = workflowNodeModel.getWorkflowNodeList(corpid, workflowId, " priority " + SortOrder.ASC);
            List<Integer> nodeList = Arrays.asList(WorkflowNodeTypeEnum.START_NODE.getType(), WorkflowNodeTypeEnum.UPDATE_NODE.getType(), WorkflowNodeTypeEnum.CREATE_NODE.getType(),
                    WorkflowNodeTypeEnum.SINGLE_DATA_NODE.getType());
            List<WorkflowNodeEntity> upNodeList = WorkflowNodeUtil.getUpNodeList(workflowNodeList, prevId, nodeList);
            Set<Long> formIdList = new HashSet<>();
            Set<Long> workOrderIdList = new HashSet<>();
            upNodeList.forEach(item->{
                if(Objects.equals(XbbRefTypeEnum.WORK_ORDER.getCode(), item.getBusinessType())) {
                    workOrderIdList.add(item.getFormId());
                } else {
                    formIdList.add(item.getFormId());
                }
            });
            Map<Long, PaasFormEntity> formMap = proFormHelp.getFormMap(formIdList, corpid, DelEnum.NORMAL.getDel());
            Map<Long, WorkOrderFormEntity> workOrderFormMap = proFormHelp.getWorkOrderFormMap(workOrderIdList, corpid, DelEnum.NORMAL.getDel());
            Map<Long, PaasFormExplainEntity> formExplainMap = proFormHelp.getFormExplainMap(formIdList, corpid);
            Map<Long, List<FieldAttrEntity>> formReturnExplain = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            // 动态负责人：提交人、负责人、协同人、成员单选、成员多选
            List<Integer>  otherDynamicFieldTypeList = Arrays.asList(FieldTypeEnum.CREATORID.getType(), FieldTypeEnum.OWNERID.getType(), FieldTypeEnum.COUSERID.getType(),
                    FieldTypeEnum.USER.getType(), FieldTypeEnum.USER_GROUP.getType());
            formExplainMap.forEach((key, explainEntity)->{
                List<FieldAttrEntity> list = JSON.parseArray(explainEntity.getExplains(), FieldAttrEntity.class);

                getDynamicManage(list, otherDynamicFieldTypeList, key, formReturnExplain);
            });
            // 工单解释
            Map<Long, WorkOrderExplainEntity> workOrderFormExplainMap = proFormHelp.getWorkOrderFormExplainMap(workOrderIdList, corpid);
            Map<Long, List<FieldAttrEntity>> workOrderReturnExplain = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            workOrderFormExplainMap.forEach((key, explainEntity)->{
                List<FieldAttrEntity> list = JSON.parseArray(explainEntity.getExplains(), FieldAttrEntity.class);
                getDynamicManage(list, otherDynamicFieldTypeList, key, workOrderReturnExplain);
            });
            List<WorkflowSourceFieldPojo> nodeFieldList = getFieldListDynamic(upNodeList, workOrderReturnExplain, formReturnExplain, formMap, workOrderFormMap);
            WorkflowDynamicManagerVO workflowDynamicManagerVO = new WorkflowDynamicManagerVO();
            workflowDynamicManagerVO.setNodeFieldList(nodeFieldList);
            return workflowDynamicManagerVO;
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOGGER.error("WorkflowSetServiceImpl.dynamicManager error：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
    }

    private void getDynamicManage(List<FieldAttrEntity> list, List<Integer> dynamicFieldTypeList, Long key, Map<Long, List<FieldAttrEntity>> formReturnExplain) {
        List<FieldAttrEntity> resultList = new ArrayList<>();
        list.forEach(item->{
            boolean isUse = Objects.equals(BasicConstant.IS_USE, item.getVisible()) && ( Objects.isNull(item.getEditHide()) || Objects.equals(item.getEditHide(), 0)) && dynamicFieldTypeList.contains(item.getFieldType());
            if (isUse) {

                if (Objects.equals(FieldTypeEnum.CREATORID.getType(), item.getFieldType())) {
                    item.setAttrName(I18nMessageUtil.getMessage(I18nStringConstant.SUBMITTER));
                }
                resultList.add(item);
            }
        });
        if (CollectionUtils.isNotEmpty(resultList)) {
            formReturnExplain.put(key, resultList);
        }
    }

    /**
     * 获取标题中可以使用的节点
     * @param type
     * @return
     */
    private List<Integer> getNodeList(Integer type) {
        List<Integer> nodeList = new ArrayList<>();
        if (Objects.equals(WorkflowNodeTypeEnum.APPROVE_NODE.getType(), type )) {
            nodeList = Arrays.asList(WorkflowNodeTypeEnum.START_NODE.getType());
        }else if (Objects.equals(WorkflowNodeTypeEnum.CC_NODE.getType(), type )) {
            nodeList = Arrays.asList(WorkflowNodeTypeEnum.START_NODE.getType());
        }else if (Objects.equals(WorkflowNodeTypeEnum.SEND_MESSAGE_NODE.getType(), type )) {
            nodeList = Arrays.asList(WorkflowNodeTypeEnum.START_NODE.getType(), WorkflowNodeTypeEnum.CREATE_NODE.getType(), WorkflowNodeTypeEnum.UPDATE_NODE.getType(), WorkflowNodeTypeEnum.SINGLE_DATA_NODE.getType());
        }
        return nodeList;
    }

    /**
     * 获取节点的字段信息
     * @param upNodeList 节点信息
     * @param workOrderFormFieldMap 工单字段信息
     * @param explainFieldMap 非工单字段信息
     * @param removeSubForm true：移除子表单；false：无需移除子表单
     * @param subFormMap 子表单容器，key为节点id；value为子表单attr
     * @return
     */
    private List<WorkflowSourceFieldPojo> getFieldList(List<WorkflowNodeEntity> upNodeList, Map<Long, List<FieldAttrEntity>> workOrderFormFieldMap,
                                                       Map<Long, List<FieldAttrEntity>> explainFieldMap, boolean removeSubForm, Map<Long, String> subFormMap,
                                                       Map<Long, PaasFormEntity> formMap, Map<Long, WorkOrderFormEntity> workOrderMap) {

        List<WorkflowSourceFieldPojo> nodeFieldList = new ArrayList<>();
        if (CollectionsUtil.isEmpty(upNodeList)) {
            return nodeFieldList;
        }
        upNodeList.forEach(item->{
            List<FieldAttrEntity> explainList;
            String name = "";
            if(Objects.equals(XbbRefTypeEnum.WORK_ORDER.getCode(), item.getBusinessType())) {
                explainList = workOrderFormFieldMap.get(item.getFormId());
                if (workOrderMap.containsKey(item.getFormId())) {
                    name = workOrderMap.get(item.getFormId()).getName();
                }
            } else {
                explainList = explainFieldMap.get(item.getFormId());
                if (formMap.containsKey(item.getFormId())) {
                    name = formMap.get(item.getFormId()).getName();
                }
            }
            if (Objects.isNull(explainList)) {
                return;
            }
            if (removeSubForm) {
                if (subFormMap.isEmpty() || !subFormMap.containsKey(item.getId())) {
                    explainList.removeIf(fieldAttrEntity-> fieldAttrEntity.getAttr().contains(FieldTypeEnum.SUB_FORM.getEsalias()));
                } else if (subFormMap.containsKey(item.getId())) {
                    explainList.removeIf(fieldAttrEntity-> (fieldAttrEntity.getAttr().contains(FieldTypeEnum.SUB_FORM.getEsalias()) && !Objects.equals(fieldAttrEntity.getParentAttr(), subFormMap.get(item.getId()))));
                }
            }
            // 需要一个list去封装字段解释，否则表单触发事件和更新数据的节点选的是同一表单会有问题
            List<FieldAttrEntity> list = new ArrayList<>();
            list.addAll(explainList);
            Integer triggerNodeFlag = 0;
            if (Objects.equals(WorkflowNodeTypeEnum.START_NODE.getType(), item.getType())) {
                triggerNodeFlag = 1;
            }
            WorkflowSourceFieldPojo workflowSourceFieldPojo = new WorkflowSourceFieldPojo(item.getName(), name, item.getId(), item.getFormId(), item.getBusinessType(), item.getSaasMark(), 0, triggerNodeFlag,  list);
            nodeFieldList.add(workflowSourceFieldPojo);
        });
        return nodeFieldList;
    }

    /**
     * 工作流动态负责人
     * @param upNodeList
     * @param workOrderFormFieldMap
     * @param explainFieldMap
     * @param formMap
     * @param workOrderFormMap
     * @return
     */
    private List<WorkflowSourceFieldPojo> getFieldListDynamic(List<WorkflowNodeEntity> upNodeList, Map<Long, List<FieldAttrEntity>> workOrderFormFieldMap,
                                                       Map<Long, List<FieldAttrEntity>> explainFieldMap, Map<Long, PaasFormEntity> formMap, Map<Long, WorkOrderFormEntity> workOrderFormMap) {

        List<WorkflowSourceFieldPojo> nodeFieldList = new ArrayList<>();
        if (CollectionsUtil.isEmpty(upNodeList)) {
            return nodeFieldList;
        }
        upNodeList.forEach(item->{
            List<FieldAttrEntity> explainList;
            String formName;
            if(Objects.equals(XbbRefTypeEnum.WORK_ORDER.getCode(), item.getBusinessType())) {
                explainList = workOrderFormFieldMap.get(item.getFormId());
                if (!workOrderFormMap.containsKey(item.getFormId())) {
                    return;
                }
                formName = workOrderFormMap.get(item.getFormId()).getName();
            } else {
                explainList = explainFieldMap.get(item.getFormId());
                if (!formMap.containsKey(item.getFormId())) {
                    return;
                }
                formName = formMap.get(item.getFormId()).getName();
            }
            if (Objects.isNull(explainList)) {
                return;
            }
            Integer triggerNodeFlag = 0;
            if (Objects.equals(WorkflowNodeTypeEnum.START_NODE.getType(), item.getType())) {
                triggerNodeFlag = 1;
            }
            String name = String.format(StringConstant.ERROR_PARAM, item.getName(), formName);
            WorkflowSourceFieldPojo workflowSourceFieldPojo = new WorkflowSourceFieldPojo(item.getName(), name, item.getId().toString(), item.getId(), item.getFormId(), item.getBusinessType(), item.getSaasMark(), 0, triggerNodeFlag,  explainList);
            nodeFieldList.add(workflowSourceFieldPojo);
        });
        return nodeFieldList;
    }

    /**
     * @param fieldAttrEntity
     * @param businessType
     * @param clazz
     * @param standard
     * @return com.xbongbong.pro.formexplain.pojo.FieldAndLogicPojo
     * @author 吴峰
     * @date 2021/6/4 11:21
     * @throws XbbException
     */
    public FieldAndLogicPojo getOperatorObject(FieldAttrEntity fieldAttrEntity, Integer businessType, Class clazz, boolean standard) throws XbbException{
        // 开启、可见及业务规则可操作字段
        boolean flag = Objects.equals(1, fieldAttrEntity.getIsOpen()) && Objects.equals(1, fieldAttrEntity.getVisible()) && Objects.nonNull(RuleOperatorFieldEnum.getByCode(fieldAttrEntity.getFieldType()));
        // 系统字段
        JSONArray attrArray = RuleOperatorBusinessFieldEnum.getAttrsByCode(businessType);
        boolean sysFlag = Objects.equals(fieldAttrEntity.getIsRedundant(), BasicConstant.ZERO) && attrArray.contains(fieldAttrEntity.getAttr());
        // 自定义字段
        boolean cusFlag = Objects.equals(fieldAttrEntity.getIsRedundant(), BasicConstant.ONE);

        if (flag && (sysFlag || cusFlag)) {
            FieldTypeEnum fieldTypeEnum = FieldTypeEnum.getFieldTypeEnum(fieldAttrEntity.getFieldType());
            if (fieldTypeEnum != null) {
                Integer fieldType = fieldAttrEntity.getFieldType();

                FieldAndLogicPojo fieldAndLogicPojo = new FieldAndLogicPojo(fieldAttrEntity.getAttr(), fieldType, fieldAttrEntity.getAttrName(), fieldAttrEntity.getVisible(), fieldAttrEntity.getEditable());
                Object object = proFormHelp.getPrivateConst(fieldTypeEnum.getAlias(), clazz);
                List<LogicPojo> logicList = proFormHelp.getLogicList(object, 1);
                // 设置值类型
                fieldAndLogicPojo.setValueTypeList(getValueTypeList(fieldType, standard));
                // 按照字段类型设置属性
                proFormHelp.setFieldAttr(fieldAttrEntity, fieldAndLogicPojo);
                fieldAndLogicPojo.setLogicList(logicList);
                return fieldAndLogicPojo;
            }
        }
        return null;
    }

    /**
     * 获取值类型
     */
    public List<ValueTypePojo> getValueTypeList(Integer fieldType, boolean standard) {
        List<ValueTypePojo> valueTypeList = new ArrayList<>();
        ValueTypePojo valueTypePojo = new ValueTypePojo(WorkflowValueTypeEnum.DYNAMIC_VALUE.getType(), WorkflowValueTypeEnum.DYNAMIC_VALUE.getName());
        valueTypeList.add(valueTypePojo);
        if (standard) {
            // 公式配置
            ValueTypePojo formula = new ValueTypePojo(WorkflowValueTypeEnum.FORMULA.getType(), WorkflowValueTypeEnum.FORMULA.getName());
            valueTypeList.add(formula);
        }
        if (!Objects.equals(FieldTypeEnum.DATAID.getType(), fieldType)
                && !Objects.equals(FieldTypeEnum.LINK_DATA.getType(), fieldType)
                && !Objects.equals(FieldTypeEnum.LINK_DATA_MULTI.getType(), fieldType)
                && !Objects.equals(FieldTypeEnum.LINK_BUSINESS_SINGLE.getType(), fieldType)
        ) {
            ValueTypePojo valueTypePojo1 = new ValueTypePojo(WorkflowValueTypeEnum.FIXED_VALUE.getType(), WorkflowValueTypeEnum.FIXED_VALUE.getName());
            valueTypeList.add(valueTypePojo1);
        }
        return valueTypeList;
    }

    private List<WorkflowConditionFieldPojo> getExplainMapByConditionNode(String explains) throws XbbException {
        List<WorkflowConditionFieldPojo> fieldAndLogicPojos = new ArrayList<>();
        List<FieldAttrEntity> explainList = JSON.parseArray(explains, FieldAttrEntity.class);
        for (FieldAttrEntity item : explainList) {
            if (WorkflowConditionEnum.conditionSet.contains(item.getFieldType())) {
                WorkflowConditionFieldPojo workflowConditionFieldPojo = new WorkflowConditionFieldPojo(item.getAttr(), item.getFieldType(), item.getAttrName(), item.getVisible(),
                        item.getEditable(), item.getSaasParticularAttributePoJo());
                FieldTypeEnum fieldTypeEnum = FieldTypeEnum.getFieldTypeEnum(item.getFieldType());
                List<ConditionClass> conditionList = ConditionListHelp.getConditionList(fieldTypeEnum, 0);
                workflowConditionFieldPojo.setConditionList(conditionList);
                fieldAndLogicPojos.add(workflowConditionFieldPojo);
                fieldAndLogicPojos.add(workflowConditionFieldPojo);
            }
        }
        return fieldAndLogicPojos;
    }

    /**
     * 返回节点标题的字段
     * @param explains
     * @return
     */
    private List<FieldAttrEntity> getExplainByTitle( String explains) {
        List<FieldAttrEntity> explainList = JSON.parseArray(explains, FieldAttrEntity.class);
        // 单行文本、数字、下拉框、日期时间、单选按钮、成员单选、部门单选、创建人、创建时间、修改时间、拥有者、协同人、流水号、关联业务单选、关联业务多选
        List<Integer> titleFieldAttrList = Arrays.asList(1, 2, 4, 3, 10000, 10009, 10011, 10013, 10014, 10015, 10016, 10017, 10018, 10019, 10030, 20001, 20002);

        return explainList.stream().filter(item -> (Objects.equals(item.getEditHide(), 0) || Objects.isNull(item.getEditHide())))
                .filter(item -> (Objects.equals(item.getShowType(), 0) || Objects.isNull(item.getShowType())))
                .filter(item -> titleFieldAttrList.contains(item.getFieldType()))
                .collect(Collectors.toList());
    }

    private List<FieldAttrEntity> getFieldList(WorkflowNodeEntity updateNode, WorkflowInsertNodeOperatorFieldDTO workflowInsertNodeOperatorFieldDTO, Object clazz,
                                               Long formId, Integer businessType, Integer saasMark, String explains, boolean condition) throws XbbException{
        boolean same = false;
        if (Objects.nonNull(updateNode)) {
            same = Objects.equals(updateNode.getFormId(), formId) && Objects.equals(updateNode.getBusinessType(), businessType);
        }
        if (same && Objects.equals(WorkflowNodeTypeEnum.UPDATE_NODE.getType(), workflowInsertNodeOperatorFieldDTO.getType())
                && Objects.equals(WorkflowValueTypeEnum.FORMULA.getType(), workflowInsertNodeOperatorFieldDTO.getValueType())) {
            List<FieldAttrEntity> explainList = JSON.parseArray(explains, FieldAttrEntity.class);
            // 获取适合作为公式的字段
            Iterator<FieldAttrEntity> iterator = explainList.iterator();
            List<FieldAttrEntity> returnExplainList = new ArrayList<>();
            while (iterator.hasNext()) {
                FieldAttrEntity fieldAttrEntity = iterator.next();
                Integer showType = fieldAttrEntity.getShowType();
                boolean invisible = Objects.nonNull(showType) && (ShowTypeEnum.LIST.getCode() == showType || ShowTypeEnum.DETAIL.getCode() == showType
                        || ShowTypeEnum.LIST_DETAIL.getCode() == showType || ShowTypeEnum.NONE.getCode() == showType);
                if (invisible || !Objects.equals(1, fieldAttrEntity.getIsOpen())) {
                    continue;
                }
                boolean isFormulaExplain = RuleFormulaExplainEnum.getFormulaExplain(fieldAttrEntity.getFieldType());
                if (isFormulaExplain) {
                    SubFormPoJo subFormPoJo = fieldAttrEntity.getSubForm();
                    if (Objects.equals(FieldTypeEnum.SUB_FORM.getType(), fieldAttrEntity.getFieldType())
                            && Objects.nonNull(subFormPoJo.getItems()) && subFormPoJo.getItems().size() != 0) {
                        List<? extends FieldAttrEntity> items = subFormPoJo.getItems();
                        for (int i = 0; i < items.size(); i++) {
                            FieldAttrEntity subField = items.get(i);
                            boolean isFormula = RuleFormulaExplainEnum.getFormulaExplain(subField.getFieldType());
                            if (isFormula) {
                                String attr = fieldAttrEntity.getAttr() + StringConstant.POINT + subField.getAttr();
                                String attrName = fieldAttrEntity.getAttrName() + StringConstant.POINT + subField.getAttrName();
                                subField.setAttr(attr);
                                subField.setAttrName(attrName);
                                returnExplainList.add(subField);
                            }
                        }
                    } else {
                        returnExplainList.add(fieldAttrEntity);
                    }
                }
            }
            return returnExplainList;
        } else {
            return getExplainByUpdateNode(workflowInsertNodeOperatorFieldDTO, clazz, formId, businessType, saasMark, explains, condition);
        }
    }
    /**
     *
     * @param workflowInsertNodeOperatorFieldDTO
     * @param formId
     * @param businessType
     * @param saasMark
     * @param explains
     * @return
     * @throws XbbException
     */
    private List<FieldAttrEntity> getExplainByUpdateNode(WorkflowInsertNodeOperatorFieldDTO workflowInsertNodeOperatorFieldDTO, Object clazz, Long formId,
                                                         Integer businessType, Integer saasMark, String explains, boolean condition) throws XbbException {
        List<FieldAttrEntity> explainList = JSON.parseArray(explains, FieldAttrEntity.class);
/**
 *  @param formId 当前表单的id
 *      * @param businessType 前表单的业务类型
 *      * @param saasMark  前表单的saas标识
 *      * @param linkFormId 关联数据关联的表单id
 *      * @param fieldType              规则对应的字段
 *      * @param fieldBusinessType 字段对应的业务类型
 *      * @param fieldTypeSet
 */
        Long linkFormId = null;
        LinkInfoPojo linkInfoPojo = workflowInsertNodeOperatorFieldDTO.getLinkInfo();
        Integer fieldBusinessType = workflowInsertNodeOperatorFieldDTO.getLinkedType();
        if (Objects.nonNull(linkInfoPojo)) {
            fieldBusinessType = linkInfoPojo.getLinkBusinessType();
            linkFormId = linkInfoPojo.getLinkFormId();
            saasMark = linkInfoPojo.getLinkSaasMark();
        }
        Integer fieldType = workflowInsertNodeOperatorFieldDTO.getFieldType();
        boolean isDataId = Objects.equals(FieldTypeEnum.DATAID.getType(), fieldType);
        if (isDataId) {
            fieldBusinessType = workflowInsertNodeOperatorFieldDTO.getBusinessType();
            linkFormId = workflowInsertNodeOperatorFieldDTO.getFormId();
            saasMark = workflowInsertNodeOperatorFieldDTO.getSaasMark();
        }

        FieldTypeEnum fieldTypeEnum = FieldTypeEnum.getFieldTypeEnum(fieldType);
        String alias = fieldTypeEnum.getAlias().toUpperCase();
        Set<Integer> fieldTypeSet = new HashSet<>();
        if (fieldTypeEnum != null && ReflectHelper.exist(clazz, alias)) {
            Integer[] array = (Integer[]) ReflectHelper.valueGet(clazz, alias);
            for (Integer integer : array) {
                fieldTypeSet.add(integer);
            }
        }

        Map<Integer, List<String>> fieldBlockMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        fieldBlockMap.put(XbbRefTypeEnum.PAYMENT_SHEET.getCode(), Arrays.asList(PaymentSheetEnum.PAY_METHOD.getAttr(), PaymentSheetEnum.FUND_ACCOUNT.getAttr()));
        fieldBlockMap.put(XbbRefTypeEnum.CONTACT.getCode(), Arrays.asList(ContactEnum.AVATAR.getAttr()));
        return getOperatorFieldList(formId, businessType, saasMark, fieldType, explainList, linkFormId, fieldBusinessType, fieldTypeSet, fieldBlockMap, condition);
    }

    /**
     * 根据规则过滤字段且包含子字段
     *
     * @param explainJsonArray 字段解释
     * @param formId 当前表单的id
     * @param businessType 前表单的业务类型
     *  @param saasMark  前表单的saas标识

     * @return
     */
    private static List<FieldAttrEntity> getOperatorFieldList(Long formId, Integer businessType, Integer saasMark, Integer fieldType, List<FieldAttrEntity> explainJsonArray, Long linkFormId, Integer fieldBusinessType,
                                                             Set<Integer> fieldTypeSet, Map<Integer, List<String>> fieldBlockMap, boolean condition) {
        List<FieldAttrEntity> jsonArray = new ArrayList<>();
        for (FieldAttrEntity fieldAttrEntity : explainJsonArray) {
            if (fieldBlockMap.containsKey(businessType)) {
                List<String> fieldBlockList = fieldBlockMap.get(businessType);
                if (fieldBlockList.contains(fieldAttrEntity.getAttr())) {
                    continue;
                }
            }
            Integer showType = fieldAttrEntity.getShowType();
            Boolean invisible = Objects.nonNull(fieldAttrEntity.getShowType()) && (ShowTypeEnum.LIST.getCode() == showType || ShowTypeEnum.DETAIL.getCode() == showType
                    || ShowTypeEnum.LIST_DETAIL.getCode() == showType || ShowTypeEnum.NONE.getCode() == showType);
            if (invisible || Objects.equals(0, fieldAttrEntity.getIsOpen()) || Objects.equals(fieldAttrEntity.getIsOpen(), 2)) {
                continue;
            }
            boolean  isLinkData = Objects.equals(FieldTypeEnum.LINK_DATA.getType(), fieldAttrEntity.getFieldType()) || Objects.equals(FieldTypeEnum.LINK_DATA_MULTI.getType(), fieldAttrEntity.getFieldType());
            if (isLinkData) {
                LinkInfoPojo linkInfoPojo1 = fieldAttrEntity.getLinkInfo();
                businessType = linkInfoPojo1.getLinkBusinessType();
                formId = linkInfoPojo1.getLinkFormId();
            }
            if (FilterExplainUtil.filterField(fieldAttrEntity, saasMark, businessType, fieldBusinessType, condition, formId, linkFormId, fieldType)) {
                // 过滤掉字段
                continue;
            }
            if (Objects.equals(FieldTypeEnum.SUB_FORM.getType(), fieldAttrEntity.getFieldType())) {
                List<? extends FieldAttrEntity> subFieldList = fieldAttrEntity.getSubForm().getItems();
                for (FieldAttrEntity item : subFieldList) {
                    // 字段回收站处理
                    if (Objects.equals(item.getIsOpen(), 2)) {
                        continue;
                    }
                    if (fieldTypeSet.contains(item.getFieldType())) {
                        isLinkData = Objects.equals(FieldTypeEnum.LINK_DATA.getType(), item.getFieldType()) || Objects.equals(FieldTypeEnum.LINK_DATA_MULTI.getType(), item.getFieldType());
                        if (isLinkData) {
                            LinkInfoPojo linkInfoPojo1 = item.getLinkInfo();
                            businessType = linkInfoPojo1.getLinkBusinessType();
                            formId = linkInfoPojo1.getLinkFormId();
                        }
                        if (FilterExplainUtil.filterField(item, saasMark, businessType, fieldBusinessType, condition, formId, linkFormId, fieldType)) {
                            // 过滤掉字段
                            continue;
                        }
                        item.setAttrName(fieldAttrEntity.getAttrName() + "." + item.getAttrName());
                        item.setAttr(fieldAttrEntity.getAttr() + "." + item.getAttr());
                        jsonArray.add(item);
                    }
                }
            } else if (fieldTypeSet.contains(fieldAttrEntity.getFieldType())) {
                jsonArray.add(fieldAttrEntity);
            }
        }
        return jsonArray;
    }


}
